package com.qf.flying;


import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;


/**
 * 主逻辑其余所有部分-潘首丞
 * */


public class ShootGame
        extends JPanel
{
    //游戏的启动类   需要添加main方法
    //设定游戏的场地宽广
    public static final int WIDTH = 400;//宽
    public static final int HEIGHT = 654;//高
    //定义图片资源对象
    public static BufferedImage background;
    public static BufferedImage fire1;
    public static BufferedImage fire2;
    public static BufferedImage fire3;
    public static BufferedImage cjj;
    public static BufferedImage k;
    public static BufferedImage boss;
    public static BufferedImage heroImg;
    public static BufferedImage gamingBackground;

    //定义游戏的状态
    private int state = 0;
    public static final int START = 0;
    public static final int RUNNING = 1;
    public static final int PAUSE = 2;
    public static final int GAMEOVER = 3;


    //定时器
    private Timer timer;//定时器
    private int interval = 10;//时间间隔

    //定义界面中的演员
    public Hero hero = new Hero();//英雄机

    public Bullet[] bullets = {};//子弹数组对象

    public FlyObject[] flings = {};//敌方数组

    volatile boolean isCleaning = false;


    //静态代码块
    static
    {
        try
        {
            //读出图片
            /**
             * 背景图制作与替换-郭涵月
             * */

            background = ImageIO.read(ShootGame.class.getResource("background.png"));
            gamingBackground = ImageIO.read(ShootGame.class.getResource("gamingBackground.png"));

            boss = ImageIO.read(ShootGame.class.getResource("boss.png"));
            k = ImageIO.read(ShootGame.class.getResource("k.png"));
            cjj = ImageIO.read(ShootGame.class.getResource("cjj.png"));
            fire1 = ImageIO.read(ShootGame.class.getResource("fire1.png"));
            fire2 = ImageIO.read(ShootGame.class.getResource("fire2.png"));
            fire3 = ImageIO.read(ShootGame.class.getResource("fire3.png"));
            heroImg = ImageIO.read(ShootGame.class.getResource("hero.png"));


        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //游戏启动方法
    public void action()
    {
        // 引入鼠标监听器
        MouseAdapter l = new MouseAdapter()
        {
            //监听鼠标移动
            @Override
            public void mouseMoved(MouseEvent e)
            {
                //会在鼠标移动的时候自动 调用这个方法
                int x = e.getX();
                int y = e.getY();
                if (state == RUNNING)
                {
                    hero.moveTo(x, y);
                }
            }

            //监听鼠标点击
            @Override
            public void mouseClicked(MouseEvent e)
            {
                if (state == START)
                {
                    state = RUNNING;
                }
                else if (state == GAMEOVER)
                {
                    //对游戏数据初始化
                    hero = new Hero();
                    flings = new FlyObject[0];
                    bullets = new Bullet[0];
                    state = START;
                }
                //全屏清空
                else if (state == RUNNING && e.getButton() == MouseEvent.BUTTON1)
                {
                    bullets = new Bullet[]{};
                    flings = new FlyObject[]{};
                    isCleaning = true;
                    new Timer().schedule(new TimerTask()
                    {
                        @Override
                        public void run()
                        {
                            isCleaning = false;
                        }
                    },500);
                }

            }

            //鼠标移出监听
            @Override
            public void mouseExited(MouseEvent e)
            {
                if (state == RUNNING)
                {
                    state = PAUSE;
                }
            }

            //鼠标移入监听
            @Override
            public void mouseEntered(MouseEvent e)
            {
                if (state == PAUSE)
                {
                    state = RUNNING;
                }
            }


        };
        //为当前面板对象添加一个监听器 鼠标移动
        this.addMouseMotionListener(l);
        //为当前面板对象添加一个监听器 鼠标点击
        this.addMouseListener(l);


        timer = new Timer();
        timer.schedule(new TimerTask()
        {
            @Override
            public void run()
            {
                if (state == RUNNING)
                {
                    //调用敌方的入场
                    flyObjectEnter();
                    //调用走步
                    flyObjectstep();
                    //子弹的入场
                    bulletEnter();
                    //子弹的走步
                    bulletsStep();
                    //英雄走步
                    hero.step();
                    //击败
                    hitTo();
                    //检查游戏是否结束
                    checkGameOverAction();
                }
                repaint();//重画

            }
        }, interval, interval); //定时器要做的事    定时器启动后 多久开始第一次生效     每隔多久生效一次
    }

    //敌方的入场  没调用一个这个方法  就生产一个敌方对象
    //定义一个计步器
    int flyObjectIndex = 0;

    public void flyObjectEnter()
    {
        flyObjectIndex++;
        if (flyObjectIndex % 30 == 0)
        {
            //出敌方
            // 随机出大蛇
            Random rad = new Random();
            int r = rad.nextInt(10);
//            r = 0;
            if (r == 0)
            {
                //创建一个K
                K k = new K();
                flings = Arrays.copyOf(flings, flings.length + 1);
                flings[flings.length - 1] = k;

            }
            else if (r == 2)
            {
                //创建一个大蛇
                Boss boss = new Boss();
                flings = Arrays.copyOf(flings, flings.length + 1);
                flings[flings.length - 1] = boss;
            }
            else
            {
                //创建一个普通敌人
                Cjj cjj = new Cjj();
                flings = Arrays.copyOf(flings, flings.length + 1);
                flings[flings.length - 1] = cjj;
            }

        }
    }

    //子弹入场
    int bulletIndex = 0;

    public void bulletEnter()
    {
        bulletIndex++;
        if (bulletIndex % hero.shootSpeed == 0)
        {
            //调用英雄开火方法  可能单发 也可能双发
            Bullet[] bs = hero.fire();
            //实现数组的扩容
            bullets = Arrays.copyOf(bullets, bullets.length + bs.length);
            System.arraycopy(bs, 0, bullets, bullets.length - bs.length, bs.length);
        }

    }

    //迭代子弹
    public void hitTo()
    {
        //被删除的敌方和子弹个数
        int deleteBulletNumbers = 0;
        int deleteFlyNumbers = 0;
        //迭代子弹
        for (int i = 0; i < bullets.length; i++)
        {
            //子弹飞出屏幕就清除
            if (bullets[i].y < -50)
            {
                bullets[i] = null;
            }
            Bullet b = bullets[i];
            for (int j = 0; j < flings.length; j++)
            {
                if (flings[j] == null || bullets[i] == null)
                {
                    break;
                }
                //敌人飞出屏幕就清除
                if (flings[j].y > 2000)
                {
                    flings[j] = null;
                    break;
                }

                boolean t = flings[j].shootBy(b);
                //判断是否击中，清除子弹
                if (flings[j].isShot(b))
                {
                    System.out.println();
                    bullets[i] = null;
                }
                //判断是否击落，清除敌人
                if (t)
                {
                    //的判断配击中的是谁
                    FlyObject f = flings[j];
                    if (f instanceof Enemy)
                    {
                        hero.score += ((Enemy) f).getScore();
                        if (flings[j].isAward)
                        {
                            hero.beAwarded(flings[j].award);
                        }
                    }

                    flings[j] = null;
      /*              flings[j] = flings[flings.length - 1 - deleteFlyNumbers];
                    flings = Arrays.copyOf(flings, flings.length - deleteBulletNumbers);*/
                    deleteFlyNumbers += 1;
                }
            }
        }
        //删除数组内null元素
        boolean canStop = false;
        do
        {
            canStop = true;
            for (int i = 0; i < bullets.length; i++)
            {
                if (bullets[i] == null)
                {
                    bullets[i] = bullets[bullets.length - 1];
                    bullets = Arrays.copyOf(bullets, bullets.length - 1);
                    canStop = false;
                    break;
                }
            }
            for (int i = 0; i < flings.length; i++)
            {
                if (flings[i] == null)
                {
                    flings[i] = flings[flings.length - 1];
                    flings = Arrays.copyOf(flings, flings.length - 1);
                    canStop = false;
                    break;
                }
            }
//            flings = Arrays.copyOf(flings, flings.length - deleteBulletNumbers);
        }
        while (!canStop);
    }


    //敌方走步
    public void flyObjectstep()
    {
        for (int i = 0; i < flings.length; i++)
        {
            flings[i].step();
        }
    }

    //定义一个子弹走步
    public void bulletsStep()
    {
        for (int i = 0; i < bullets.length; i++)
        {
            bullets[i].step();
        }
    }

    //检查游戏是否结束
    public void checkGameOverAction()
    {
        if (isGameOver())
        {
            state = GAMEOVER;
        }

    }

    //判断游戏是否结束
    public boolean isGameOver()
    {
        for (int i = 0; i < flings.length; i++)
        {
            int index = -1;//记录碰撞敌方的下标
            FlyObject obj = flings[i];
            if (hero.hit(obj))
            {
                //如果与敌方碰撞
                hero.subtractLife();
                //清除所有加成
                hero.noMoreAward();
                //记录与英雄碰撞的敌方下标
                index = i;
            }
            //删除与英雄碰撞的敌方
            if (index != -1)
            {
                flings[index] = flings[flings.length - 1];
                flings = Arrays.copyOf(flings, flings.length - 1);
            }
        }
        return hero.getLife() <= 0;
    }


    //绘图
    @Override
    public void paint(Graphics g)
    {
        super.paint(g);
        if (isCleaning)
        {
            g.setColor(Color.RED);
            g.fillRect(0,0,1600,1000);
            return;
        }
        if (state == RUNNING)
        {
            g.drawImage(gamingBackground, 0, 0, null);//画背景
        }
        else
        {
            g.drawImage(background, 0, 0, null);//画背景
        }

        paintHero(g);
        //调用画敌方方法
        paintFlyObjects(g);
        //调用画子弹方法
        paintBullets(g);
        //画分数
        paintLife(g);
        //定义画游戏状态方法
        paintState(g);//画状态
    }

    //画状态
    public void paintState(Graphics g)
    {
        switch (state)
        {
            case START:
                g.drawString("开始游戏", 100, 100);
                break;
            case PAUSE:
                g.drawString("游戏暂停", 100, 100);
                break;
            case GAMEOVER:
                g.drawString("游戏结束", 100, 100);
                break;
        }
    }


    //封装画英雄方法
    public void paintHero(Graphics g)
    {
        g.drawImage(hero.image, hero.x, hero.y, null);//英雄
    }

    //画子弹
    public void paintBullets(Graphics g)
    {
        for (int i = 0; i < bullets.length; i++)
        {
            Bullet b = bullets[i];
            g.drawImage(b.image, b.x, b.y, null);
        }

    }

    //画敌方
    public void paintFlyObjects(Graphics g)
    {
        for (int i = 0; i < flings.length; i++)
        {
            FlyObject f = flings[i];
            g.drawImage(f.image, f.x, f.y, null);
            g.setColor(Color.RED);
            try
            {
                g.fillRect(f.x,f.y,((int)(f.image.getWidth()*(1.0 * f.life/ f.totalLife))),10);
            }
            catch (Exception e)
            {
//                System.out.println(f);
            }
        }
    }

    //画分数和生命值
    public void paintLife(Graphics g)
    {
        //设置文字的字体和大小
        g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 25));
        //设置画笔的颜色
        g.setColor(Color.RED);
        g.drawString("SCORE=" + hero.score, 10, 25);
        g.drawString("LIFE=" + hero.getLife(), 10, 45);
    }

    public static void main(String[] args)
    {
        //使用java 自带的图形页面展现 场景
        JFrame frame = new JFrame();//创建一个画框

        ShootGame shoot = new ShootGame();

        frame.add(shoot);//将画板添加到话框
        frame.setSize(background.getWidth(), background.getHeight());//设置话框的宽高
        frame.setAlwaysOnTop(true);//总在最上方
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭画框的时候自动关闭程序
        frame.setLocationRelativeTo(null);//居中
        frame.setVisible(true);//显示画框
        shoot.action();
    }

}
